﻿
using System;
using System.Data.SqlClient;
using System.Globalization;
using System.Runtime.Serialization;
using ProtoBuf;/*https://github.com/ServiceStack/ServiceStack/tree/master/lib*/
using ServiceStack.Text;/*https://github.com/ServiceStack/ServiceStack.Text*/
using V82;
using V82.ОбщиеОбъекты;
using V82.СправочникиСсылка;
using V82.СправочникиОбъект;
using V82.ДокументыСсылка;
using V82.Перечисления;//Ссылка;
namespace V82.СправочникиОбъект
{
	[ProtoContract]
	[DataContract]
	public partial class РегламентированныеОтчеты:СправочникОбъект
	{
		public bool _ЭтоНовый;
		public bool ЭтоНовый()
		{
			return _ЭтоНовый;
		}
		[DataMember]
		[ProtoMember(1)]
		public Guid Ссылка {get;set;}
		[DataMember]
		[ProtoMember(2)]
		public long Версия {get;set;}
		[DataMember]
		[ProtoMember(3)]
		public string ВерсияДанных {get;set;}
		/*static хэш сумма состава и порядка реквизитов*/
		/*версия класса восстановленного из пакета*/
		[DataMember]
		[ProtoMember(4)]
		public bool ПометкаУдаления {get;set;}
		[DataMember]
		[ProtoMember(5)]
		public bool Предопределенный {get;set;}
		[DataMember]
		[ProtoMember(6)]
		public V82.СправочникиСсылка.РегламентированныеОтчеты Родитель {get;set;}
		[DataMember]
		[ProtoMember(7)]
		public bool ЭтоГруппа {get;set;}
		[DataMember]
		[ProtoMember(8)]
		public string/*6*/ Код {get;set;}
		[DataMember]
		[ProtoMember(9)]
		public string/*100*/ Наименование {get;set;}
		[DataMember]
		[ProtoMember(10)]
		public string/*(255)*/ ИсточникОтчета {get;set;}//Источник отчета
		[DataMember]
		[ProtoMember(11)]
		public bool НеПоказыватьВСписке {get;set;}//Не показывать в списке
		///<summary>
		///Любая дополнительная информация
		///</summary>
		[DataMember]
		[ProtoMember(12)]
		public string/*(0)*/ Описание {get;set;}
		[DataMember]
		[ProtoMember(13)]
		public bool ВнешнийОтчетИспользовать {get;set;}//Использовать внешний отчет
		[DataMember]
		[ProtoMember(14)]
		public ХранилищеЗначения ВнешнийОтчетХранилище {get;set;}//Хранилище с внешним отчетом
		[DataMember]
		[ProtoMember(15)]
		public ХранилищеЗначения Периоды {get;set;}
		[DataMember]
		[ProtoMember(16)]
		public string/*(32)*/ ВнешнийОтчетВерсия {get;set;}//Версия внешнего отчета
		public void Записать()
		{
			//Установка блокировки элемента на горизантально масштабированный кластер.
			//Опционально введение тайм аута на запись одного и того же объекта, не чаще раза в 5-секунд. Защита от спама. упращение алгоритма блокировки.
			//Выделение сервиса для блокировки элемента и генерации кода
			//Выполнение операций контроля без обращений к sql-серверу.
			//Контроль конфликта блокировок.
			//Контроль загрузки булкинсертом гетерогенной коллекции.
			//Контроль уникальности кода для справочников.
			//Контроль уникальности номера для документов, в границах префикса.
			//Контроль владельца, он не может быть группой.
			//Контроль владельца он должен быть задан.
			//Контроль родителя он должен быть группой.
			//Контроль количества уровней, должен соотвествовать метаданным.
			//Контроль версии, объект не должен был быть записан перед чтением текущей записи, алгоритм версионника.
			//Контроль уникальности ссылки
			//Контроль зацикливания
			//Опционально контроль битых ссылок.
			//Соблюдейние транзакционности. ПередЗаписью. Открытие транзации. Валидации. ПриЗаписи. Фиксация транзакции. Информирование о записи элемента.
			using (var Подключение = new SqlConnection(СтрокаСоединения))
			{
				Подключение.Open();
				using (var Команда = Подключение.CreateCommand())
				{
					if(_ЭтоНовый)
					{
						Команда.CommandText = @"
						Insert Into _Reference141(
						_IDRRef
						/*,_Version*/
						,_Marked
						,_IsMetadata
						,_ParentIDRRef
						,_Folder
						,_Code
						,_Description
						,_Fld1724
						,_Fld1725
						,_Fld1726
						,_Fld1727
						,_Fld1728
						,_Fld1729
						,_Fld26592)
						Values(
						@Ссылка
						/*,@Версия*/
						,@ПометкаУдаления
						,@Предопределенный
						,@Родитель
						,@ЭтоГруппа
						,@Код
						,@Наименование
						,@ИсточникОтчета
						,@НеПоказыватьВСписке
						,@Описание
						,@ВнешнийОтчетИспользовать
						,@ВнешнийОтчетХранилище
						,@Периоды
						,@ВнешнийОтчетВерсия)";
					}
					else
					{
						Команда.CommandText = @"
						Update _Reference141
						Set
						/*_IDRRef	= @Ссылка*/
						/*,_Version	= @Версия*/
						_Marked	= @ПометкаУдаления
						,_IsMetadata	= @Предопределенный
						,_ParentIDRRef	= @Родитель
						,_Folder	= @ЭтоГруппа
						,_Code	= @Код
						,_Description	= @Наименование
						,_Fld1724	= @ИсточникОтчета
						,_Fld1725	= @НеПоказыватьВСписке
						,_Fld1726	= @Описание
						,_Fld1727	= @ВнешнийОтчетИспользовать
						,_Fld1728	= @ВнешнийОтчетХранилище
						,_Fld1729	= @Периоды
						,_Fld26592	= @ВнешнийОтчетВерсия
						Where _IDRRef = @Ссылка";
					}
					Команда.Parameters.AddWithValue("Ссылка", Ссылка.ToByteArray());
					/*Команда.Parameters.AddWithValue("Версия", Версия);*/
					Команда.Parameters.AddWithValue("ПометкаУдаления", ПометкаУдаления);
					Команда.Parameters.AddWithValue("Предопределенный", Предопределенный);
					Команда.Parameters.AddWithValue("Родитель", Родитель);
					Команда.Parameters.AddWithValue("ЭтоГруппа", ЭтоГруппа?new byte[]{0}:new byte[]{1});
					Команда.Parameters.AddWithValue("Код", Код);
					Команда.Parameters.AddWithValue("Наименование", Наименование);
					Команда.Parameters.AddWithValue("ИсточникОтчета", ИсточникОтчета);
					Команда.Parameters.AddWithValue("НеПоказыватьВСписке", НеПоказыватьВСписке);
					Команда.Parameters.AddWithValue("Описание", Описание);
					Команда.Parameters.AddWithValue("ВнешнийОтчетИспользовать", ВнешнийОтчетИспользовать);
					Команда.Parameters.AddWithValue("ВнешнийОтчетХранилище",new byte[0]);
					Команда.Parameters.AddWithValue("Периоды",new byte[0]);
					Команда.Parameters.AddWithValue("ВнешнийОтчетВерсия", ВнешнийОтчетВерсия);
					Команда.ExecuteNonQuery();
				}
			}
		}
		public void Удалить()
		{
			using (var Подключение = new SqlConnection(СтрокаСоединения))
			{
				Подключение.Open();
				using (var Команда = Подключение.CreateCommand())
				{
					Команда.CommandText = @"Delete _Reference141
					Where _IDRRef=@Ссылка";
					Команда.Parameters.AddWithValue("Ссылка", Ссылка.ToByteArray());
					Команда.ExecuteNonQuery();
				}
			}
		}
		/*МодульОбъекта*/
		////////////////////////////////////////////////////////////////////////////////
		// ПРОЦЕДУРЫ И ФУНКЦИИ ОБЩЕГО НАЗНАЧЕНИЯ
		// Функция определяет тип указанного в реквизите ИсточникОтчета
		// элемента справочника регламентированного отчета (обработки).
		//
		// Параметры
		//  ФайлВнешнегоОтчета - строка - имя файла, указанное в реквизите элемента;
		//  Расширение         - строка - расширение файла;
		//
		// Возвращаемое значение:
		// - число, принимает значения:
		//      - 1 - в реквизите указано наименование
		//            встроенного в конфигурацию отчета;
		//      - 2 - в реквизите указано полное наименование файла.
		//      - 0 - в иных случаях.
		//

		public object ОпределитьТипОтчета(/*ФайлВнешнегоОтчета, Расширение = "", НеВыводитьСообщения = Ложь*/)
		{
			//ТипОтчета = 0;
			if(true/*Не ПустаяСтрока(ФайлВнешнегоОтчета)*/)
			{
				//ФайлВнешОтчета = Новый Файл(ФайлВнешнегоОтчета);
				if(true/*ФайлВнешОтчета.Существует()*/)
				{
					//ТипОтчета  = 1;
					//Расширение = ФайлВнешОтчета.Расширение;
				}
				if(true/*ТипОтчета = 0*/)
				{
					if(true/*НЕ НеВыводитьСообщения*/)
					{
						//Сообщить("Не найден отчет """ + ФайлВнешнегоОтчета + """!", СтатусСообщения.Внимание);
					}
				}
			}
			return null;
		}
		// ОпределитьТипОтчета()
		// Формирует код нового элемента (группы) справочника
		// в соответствии с иерархической структурой последнего.
		//

		public void ГенерироватьНовыйКод(/**/)
		{
			/*// Код элемента имеет представление:
*/
			/*//  ГГГЭЭЭ, где
*/
			/*//    ГГГ - порядковый номер группы или элементов верхнего уровня;
*/
			/*//    ЭЭЭ - порядковый номер элемента внутри группы.
*/
			/*//
*/
			/*// Порядковые номера определяются с лидирующими нулями.
*/
			if(true/*ЭтоГруппа ИЛИ Уровень() = 0*/)
			{
				if(true/*ЭтоНовый()*/)
				{
					//УстановитьНовыйКод();
				}
				//ТекКод      = Код;
				//КодГруппы   = Число(Лев(ТекКод, 3)) + 1;
				//Код         = Формат(КодГруппы, "ЧЦ=3; ЧВН=;") + "000";
			}
		}
		// ГенерироватьНовыйКод()
		// Процедура генерирует код перемещаемого элемента (группы) справочника,
		// а также код расположенного рядом элемента при интерактивном перемещении
		// элемента в форме списка справочника.
		// Записывает переставляемые элементы с измененными кодами.
		// В случае сдвига группы элементов также изменяет коды вложенных в группу
		// элементов.
		//
		// Параметры
		//  Направление  – число – напрвление сдвига элемента,
		//                 принимает значения:
		//                      1 - при сдвиге вниз;
		//                     -1 - при сдвиге вверх.
		//

		public void ИзменитьКод(/*Направление*/)
		{
			//ТекущийКод    = Код;
			//СписокКодов   = Новый СписокЗначений;
			//РегламОтчеты  = Справочники.РегламентированныеОтчеты;
			//ВыборкаОтчеты = РегламОтчеты.Выбрать(Родитель, Владелец, , "Код Убыв");
			while(true/*ВыборкаОтчеты.Следующий()*/)
			{
				//СписокКодов.Добавить(ВыборкаОтчеты.Код);
			}
			if(true/*СписокКодов.Количество() < 2*/)
			{
				/*// На данном уровне имеется только один элемент или группа справочника.
*/
				/*// Игнорируем действие пользователя.
*/
			}
			/*// Открываем транзакцию
*/
			//НачатьТранзакцию();
			//ПорядковыйНомер = СписокКодов.Индекс(СписокКодов.НайтиПоЗначению(ТекущийКод));
			if(true/*(ПорядковыйНомер = 0) И (Направление < 0)*/)
			{
				/*// Попытка перемещения первого по порядку элемента вверх.
*/
				//ИндексЭлементаЗамены = СписокКодов.Количество() - 1;
			}
			//КодЭлементаЗамены     = СписокКодов.Получить(ИндексЭлементаЗамены).Значение;
			//ЭлементЗаменыСсылка   = РегламОтчеты.НайтиПоКоду(КодЭлементаЗамены,,Родитель, Владелец);
			if(true/*ЭлементЗаменыСсылка <> РегламОтчеты.ПустаяСсылка()*/)
			{
				//ЭлементЗамены     = ЭлементЗаменыСсылка.ПолучитьОбъект();
				//ТекущийКод        = ЭлементЗамены.Код;
				//ЭлементЗамены.Код = Код;
				if(true/*ЭлементЗамены.ЭтоГруппа*/)
				{
					/*// Переписываем коды вложенных в группу элементов.
*/
					//ВыборкаОтчеты = РегламОтчеты.Выбрать(ЭлементЗаменыСсылка, ЭлементЗамены.Владелец, , "Код Убыв");
					while(true/*ВыборкаОтчеты.Следующий()*/)
					{
						//ЭлементЗамены2     = ВыборкаОтчеты.ПолучитьОбъект();
						//ЭлементЗамены2.Код = Лев(ЭлементЗамены.Код, 3) + Прав(ЭлементЗамены2.Код, 3);
					}
					//;;
				}
			}
			/*// записываем перемещаемый элемент с новым кодом
*/
			//Код = ТекущийКод;
			//Записать();
			if(true/*ЭтоГруппа*/)
			{
				/*// Переписываем коды вложенных в группу элементов.
*/
				//ВыборкаОтчеты = РегламОтчеты.Выбрать(ЭтотОбъект.Ссылка, Владелец, , "Код Убыв");
				while(true/*ВыборкаОтчеты.Следующий()*/)
				{
					//ЭлементЗамены2     = ВыборкаОтчеты.ПолучитьОбъект();
					//ЭлементЗамены2.Код = Лев(ЭлементЗамены.Код, 3) + Прав(ЭлементЗамены2.Код, 3);
				}
				//;;
			}
			/*// Завершаем транзакцию
*/
			//ЗафиксироватьТранзакцию();
		}
		// ИзменитьКод()
		////////////////////////////////////////////////////////////////////////////////
		// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ ОБЪЕКТА
		// Процедура - обработчик события "ПередЗаписью" формы.
		//

		public void ПередЗаписью(/*Отказ*/)
		{
			if(true/*ОбменДанными.Загрузка*/)
			{
			}
			if(true/*Не ЭтоНовый()*/)
			{
				//ПрежнийРодитель = Ссылка.Родитель;
				if(true/*ПрежнийРодитель <> Родитель*/)
				{
					/*// В случае, когда объект сменил родителя (переместили элемент
*/
					/*// из одной группы в другую), для обеспечения настроенного порядка
*/
					/*// следования элементов переопределяем код объекта в соответствии
*/
					/*// с порядком следования элементов текущего уровня иерархии.
*/
					/*//
*/
					/*// Принимаем следующие правила:
*/
					/*// при перемещении объекта из одной группы в другую
*/
					/*// размещаем его в конец списка вложенных в группу элементов.
*/
					/*//
*/
					/*// В соответствии спинятыми правилами формируем новый код объекта:
*/
					//СписокКодов    = Новый СписокЗначений;
					//РегламОтчеты   = Справочники.РегламентированныеОтчеты;
					//ВыборкаОтчеты  = РегламОтчеты.Выбрать(Родитель, Владелец, , "Код Возр");
					while(true/*ВыборкаОтчеты.Следующий()*/)
					{
						//СписокКодов.Добавить(ВыборкаОтчеты.Код);
					}
					if(true/*СписокКодов.Количество() = 0*/)
					{
						/*// На данном уровне не имеется элементов справочника.
*/
						/*// Объекту присваиваем самый первый код.
*/
						//НовыйКодГруппы   = "001";
						//НовыйКодЭлемента = "001";
					}
					if(true/*Уровень() > 0*/)
					{
						/*// В случае, когда объект был перемещен в группу.
*/
						//НовыйКодГруппы   = Лев(Родитель.Код, 3);
					}
					/*// В соответствии с принятыми обозначениями код объекта формируется из порядкового
*/
					/*// кода группы и порядкового кода элемента внутри группы.
*/
					//Код = НовыйКодГруппы + НовыйКодЭлемента;
				}
			}
			if(true/*НЕ ЭтоГруппа И ВнешнийОтчетХранилище.Получить() = Неопределено*/)
			{
				//ВнешнийОтчетВерсия = Неопределено;
			}
		}
		// ПередЗаписью()
	}
}